package com.rt.generalframework.core.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MarshallerUtils {
	
	private static String xmlCoding = "UTF-8";

	/*@Autowired
	private Jaxb2Marshaller marshaller;

	public <T> T xmlToObject(String xml, Class<T> requiredType) {
		try {
			Source source = new StreamSource(new StringReader(xml));
			@SuppressWarnings("unchecked")
			T obj = (T) marshaller.unmarshal(source);
			return obj;
		} catch (Exception e) {
			throw new RuntimeException(String.format("xml解析失败", xml), e);
		}
	}*/
	
	/**
	 * 从xml文件读取报文
	 * 
	 * @param absPath
	 *            绝对路径
	 * @param fileName
	 *            文件名
	 */
	public Object toBeanFromFile(String absPath, String fileName, Class type)
			throws Exception {
		String filePath = absPath + fileName;
		InputStream ins = null;
		try {
			ins = new FileInputStream(new File(filePath));
		} catch (Exception e) {
			throw new Exception("读{" + filePath + "}文件失败！", e);
		}
		Object obj = null;
		try {
			Unmarshaller unMar = createUnMarshallerByType(type);
			// ByteArrayInputStream bais = new ByteArrayInputStream();
			obj = unMar.unmarshal(ins);
		} catch (Exception e) {
			throw new Exception("解析{" + filePath + "}文件失败！", e);
		}
		if (ins != null)
			ins.close();
		return obj;
	}
	
	private Marshaller createMarshallerByType(Class type) {
		Marshaller mar = null;
		try {
			JAXBContext jax = JAXBContext.newInstance(type);
			mar = jax.createMarshaller();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mar;
	}

	private Unmarshaller createUnMarshallerByType(Class type) {
		Unmarshaller unMar = null;
		try {
			JAXBContext jax = JAXBContext.newInstance(type);
			unMar = jax.createUnmarshaller();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return unMar;
	}

	/**
	 * parse XML Object to XML String
	 * 
	 * @param obj
	 * @return
	 */
	public String parseObjectXmlData(Object obj) {
		String backXml = null;
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			Marshaller mar = createMarshallerByType(obj.getClass());
			mar.marshal(obj, baos);
			backXml = baos.toString();
			backXml = new String(baos.toByteArray(), xmlCoding);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return backXml;
	}

	/***
	 * if enCoding is null ,the
	 * 
	 * @param obj
	 * @param enCoding
	 * @return
	 */
	public String parseObjectXmlData(Object obj, String enCoding) {
		String backXml = null;
		try {
			if (enCoding != null)
				xmlCoding = enCoding;
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			Marshaller mar = createMarshallerByType(obj.getClass());
			mar.setProperty(Marshaller.JAXB_ENCODING,xmlCoding);
			mar.marshal(obj, baos);
			backXml = baos.toString();
			backXml = new String(baos.toByteArray(), xmlCoding);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return backXml;
	}

	/**
	 * 
	 * default xmlCoding is UTF-8
	 * 
	 * @param type
	 * @param xmlData
	 * @return
	 */
	public Object parseXmlDataObject(Class type, String xmlData) {
		if (xmlData == null || xmlData.trim().length() == 0)
			return null;
		try {
			Unmarshaller unMar = createUnMarshallerByType(type);
			ByteArrayInputStream bais = new ByteArrayInputStream(xmlData
					.getBytes(xmlCoding));
			return unMar.unmarshal(bais);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public Object parseXmlDataObject(Class type, String xmlData,
			String enCoding) {
		if (xmlData == null || xmlData.trim().length() == 0)
			return null;
		try {
			xmlCoding = enCoding;
			Unmarshaller unMar = createUnMarshallerByType(type);
			ByteArrayInputStream bais = new ByteArrayInputStream(xmlData
					.getBytes(xmlCoding));
			return unMar.unmarshal(bais);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
